package weaver.workflow.actionsupport;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import weaver.general.Util;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.Cell;
import weaver.soa.workflow.request.DetailTable;
import weaver.soa.workflow.request.Property;
import weaver.soa.workflow.request.RequestInfo;
import weaver.soa.workflow.request.Row;
import weaver.workflow.actionsupport.Node.Src;

public class ActionConfig implements Action {
	private static Log log = LogFactory.getLog(ActionConfig.class);
	private static Map<String,TreeMap<Class<?>,Map<Node, List<Method>>>> 
		classLoadMap = new HashMap<String,TreeMap<Class<?>,Map<Node,List<Method>>>>();

	/**
	 * 封装数据
	 */
	public String execute(RequestInfo requestInfo) {

		//封装流程数据
		Map<String,String> infoMap = new HashMap<String,String>();
		String workflowid = requestInfo.getWorkflowid();
		String nodeid = String.valueOf(requestInfo.getRequestManager().getNodeid());
		infoMap.put("workflowid", workflowid);
		infoMap.put("requestid", requestInfo.getRequestid());
		infoMap.put("nodeid", nodeid);
		infoMap.put("requestname", requestInfo.getRequestManager().getRequestname());
		infoMap.put("formid", String.valueOf(requestInfo.getRequestManager().getBillid()));
		infoMap.put("formtable", requestInfo.getRequestManager().getBillTableName());
		infoMap.put("nodetype", requestInfo.getRequestManager().getNodetype());
		
		//封装表数据
		Map<String,String> mainMap=new HashMap<String,String>();
		Property[] properties = requestInfo.getMainTableInfo().getProperty();
		for (int i = 0; i < properties.length; i++) {
			String name = properties[i].getName();
			String value = Util.null2String(properties[i].getValue());
			mainMap.put(name, value);
		}

		//封装明细表
		List<List<Map<String,String>>> detailList = new ArrayList<List<Map<String,String>>>();
		DetailTable[] detailtable = requestInfo.getDetailTableInfo().getDetailTable();
		if(detailtable.length>0){
			for (int i = 0; i < detailtable.length; i++) {
				List<Map<String,String>> tableList=new ArrayList<Map<String,String>>();
				DetailTable dt = detailtable[i];// 指定明细表
				Row[] s = dt.getRow();// 当前明细表的所有数据,按行存储
				for (int j = 0; j < s.length; j++) {
					Map<String,String> colMap=new HashMap<String,String>();
					Row r = s[j];// 指定行
					Cell c[] = r.getCell();// 每行数据再按列存储
					for (int k = 0; k < c.length; k++) {
						Cell c1 = c[k];// 指定列
						String name = c1.getName();// 明细字段名称
						String value = c1.getValue();// 明细字段的值 
					    if(name!=null){
					    	colMap.put(name, value);
					    }
					}
					//列数据到行
					tableList.add(colMap);
				}
				//行数据到表
				detailList.add(tableList);
			}
		}
		
		//执行结果
		String res = ActionSupport.SUCCESS;
		try {
			//如果未扫描过，则开始扫描文件并加载class
			if(classLoadMap.size()==0 || classLoadMap.get(workflowid)==null){
				TreeMap<Class<?>,Map<Node,List<Method>>> 
					classMap = new TreeMap<Class<?>,Map<Node,List<Method>>>();
				for(Class<?> clazz : new ClassScaner().execute()){
					//初始化空的方法集合对象
					Map<Node,List<Method>> methodsMap = new HashMap<Node,List<Method>>();
					Method[] methods = clazz.getDeclaredMethods();  
			    	for (Annotation c_annotation : clazz.getAnnotations()) { 
			    		Workflow workflow = (Workflow) c_annotation;
					    for(Method method : methods){
					    	for (Annotation m_annotation : method.getAnnotations()) {
					    		Node node = (Node) m_annotation;
					    		if(methodsMap.get(node)!=null){
					    			List<Method> list = methodsMap.get(node);
					    			list.add(method);
					    			methodsMap.put(node, list);
					    		}else{
					    			List<Method> list = new ArrayList<Method>();
					    			list.add(method);
					    			methodsMap.put(node, list);
					    		}
					    	}
					    }
				    	classMap.put(clazz, methodsMap);
						classLoadMap.put(String.valueOf(workflow.id()), classMap);
			    	}
				}
			}

			//开始执行方法
			TreeMap<Class<?>, Map<Node, List<Method>>> clazzMap = classLoadMap.get(workflowid);
			if(clazzMap!=null){
				Class<?> clazz = clazzMap.firstEntry().getKey();
				Map<Node, List<Method>> methods = clazzMap.firstEntry().getValue();
				if(methods.size()!=0){
					Object entity = (Object) clazz.newInstance();
					//开始初始化父类数据
					Method initMethod = clazz.getMethod("init", new Class[]{RequestInfo.class,Map.class,Map.class,List.class,Log.class});
					initMethod.invoke(entity, new Object[]{requestInfo, infoMap, mainMap, detailList, LogFactory.getLog(clazz)});
					//开始执行对应节点的方法
					for(Node node : methods.keySet()){
						if((node.id()==0 || nodeid.equalsIgnoreCase(String.valueOf(node.id())))
								&& (node.src()==Src.ALL || requestInfo.getRequestManager().getSrc().equalsIgnoreCase(node.src().toString()))){
							for(Method execute : methods.get(node)){
								res = (String) execute.invoke(entity, new Object[]{});
								//如有异常，则打印信息并退出循环体
								if(!ActionSupport.SUCCESS.equals(res)){
									requestInfo.getRequestManager().setMessageid("9999");
									requestInfo.getRequestManager().setMessagecontent(res);
									logException(new Exception(res));
									return ActionSupport.SUCCESS;
								}
							}
						}
					}
				}else{
					logException(new Exception("错误：工作流ID"+workflowid+"节点"+nodeid+"没有找到可执行的方法，请检查！"));
				}
			}else{
				logException(new Exception("错误：工作流ID"+workflowid+"节点"+nodeid+"没有找到可执行的类，请检查！"));
			}
		} catch (IllegalAccessException e) {
			logException(e);
		} catch (Exception e) {
			logException(e);
		}
		return ActionSupport.SUCCESS;
	}
	
	private void logException(Exception e){
		StringWriter sw = new StringWriter();
		e.printStackTrace(new PrintWriter(sw,true));   
		String str=sw.toString();   
		log.error(str);
	}
}